using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;

namespace IQIGame.Onigao.GamePlay
{
    public class UIN_HeroSkill : UIBaseNode
    {

        #region Template Generate,don't modify
        protected partial class UIB_UIN_HeroSkill
        {
            #region ObjectBinding Generate
            public UnityEngine.GameObject skillRoot { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textName { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textType { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textCost { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textCooldown { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textDes { protected set; get; }
            public UnityEngine.GameObject preview { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnPreview { protected set; get; }
            public UnityEngine.GameObject upProgress { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textDesPreview { protected set; get; }
            public UnityEngine.GameObject upNeed { protected set; get; }
            public UnityEngine.GameObject commonItem { protected set; get; }
            public UnityEngine.GameObject costMoney { protected set; get; }
            public IQIGame.Onigao.Framework.ExButton btnUp { protected set; get; }
            public UnityEngine.GameObject tipState { protected set; get; }
            public IQIGame.Onigao.Framework.ExText textState { protected set; get; }
            public virtual void InitBinding(ObjectBinding __binding)
            {
                __binding.TryGetVariableValue<UnityEngine.GameObject>("skillRoot", out var __tbv0);
                skillRoot = __tbv0;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textName", out var __tbv1);
                textName = __tbv1;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textType", out var __tbv2);
                textType = __tbv2;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textCost", out var __tbv3);
                textCost = __tbv3;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textCooldown", out var __tbv4);
                textCooldown = __tbv4;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textDes", out var __tbv5);
                textDes = __tbv5;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("preview", out var __tbv6);
                preview = __tbv6;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnPreview", out var __tbv7);
                btnPreview = __tbv7;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("upProgress", out var __tbv8);
                upProgress = __tbv8;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textDesPreview", out var __tbv9);
                textDesPreview = __tbv9;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("upNeed", out var __tbv10);
                upNeed = __tbv10;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("commonItem", out var __tbv11);
                commonItem = __tbv11;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("costMoney", out var __tbv12);
                costMoney = __tbv12;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExButton>("btnUp", out var __tbv13);
                btnUp = __tbv13;
                __binding.TryGetVariableValue<UnityEngine.GameObject>("tipState", out var __tbv14);
                tipState = __tbv14;
                __binding.TryGetVariableValue<IQIGame.Onigao.Framework.ExText>("textState", out var __tbv15);
                textState = __tbv15;
            }
            #endregion ObjectBinding Generate 
        }
        #endregion Template Generate,don't modify

        #region fields & properties
        private IrregularListAdapter<UIN_HeroSkillUnit> irregularList;
        private UIN_CostMoney costMoney;
        private ListScrollAdapter<UIN_CostItem> costItems;
        private ListScrollAdapter<UIN_CommonDarkLight> upProgress;

        private HeroData heroData;
        private HeroSkill heroSkill;
        private int selectIndexSkill = -1;

        protected UIB_UIN_HeroSkill ui { get; set; }
        #endregion

        protected override void BeforeInit()
        {
            ui = new UIB_UIN_HeroSkill();
            ui.InitBinding(csObjBind);
        }

        protected override void OnInit()
        {
            irregularList = InitIrregularList<UIN_HeroSkillUnit>(ui.skillRoot, OnSkillChanged);
            irregularList.InitUnitSelected(UnitSelectType.ByExButton, OnSkillSelectd, OnSkillUnSelect);
            upProgress = InitListScroll<UIN_CommonDarkLight>(ui.upProgress, OnUpProtressChanged);

            costMoney = InitChildNode<UIN_CostMoney>(ui.costMoney);
            costItems = InitListScroll<UIN_CostItem>(ui.commonItem, OnCostItemChanged);

            ui.btnPreview.onClick.AddListener(OnClickPreview);
            ui.btnUp.onClick.AddListener(OnClickUp);
        }

        protected override void OnShow()
        {

        }

        protected override void OnHide()
        {

        }

        protected override void OnDispose()
        {
            heroData = null;
            irregularList = null;
        }

        public void Show(HeroData data)
        {
            Show();
            SetData(data);
            ShowSkillList();
        }

        private void SetData(HeroData data)
        {
            this.heroData = data;
            OnSetDataInitSelectedSkill();
        }

        private void OnSetDataInitSelectedSkill()
        {
            selectIndexSkill = -1;
            for (int i = 0; i < APIUIHeroInfo.DefaultSkillCount; i++)
            {
                HeroSkill heroSkill = GetHeroSkillByIndex(i);
                if (heroSkill.cfgData.SkillSlot == APIUIHeroInfo.DefaultUpSkillSlot)
                {
                    selectIndexSkill = i;
                    break;
                }
            }
        }

        private HeroSkill GetHeroSkillByIndex(int index)
        {
            return heroData.skills[heroData.cfgData.DefaultSkill[index]];
        }

        private void ShowSkillList()
        {
            int cnt = APIUIHeroInfo.DefaultSkillCount;
            int selectIndex = selectIndexSkill == -1 ? 0 : selectIndexSkill;
            irregularList.RefillCells(cnt, selectIndex);
        }

        private void OnSkillChanged(UIN_HeroSkillUnit item, int index)
        {
            item.Show(heroData, index);
        }

        private void OnSkillSelectd(int index, UIN_HeroSkillUnit item)
        {
            item.SetSelected(true);
            selectIndexSkill = index;
            ShowSelectdSkill(GetHeroSkillByIndex(index));
        }

        private void OnSkillUnSelect(int index, UIN_HeroSkillUnit item)
        {
            item.SetSelected(false);
        }

        private void ShowSelectdSkill(HeroSkill heroSkill)
        {
            this.heroSkill = heroSkill;
            ShowSkillBase();
            if (IsCanUp())
            {
                ShowUpProgress();
                ShowSkillUp();
            }
            ui.btnPreview.SetActive(IsCanPreview());
            ui.preview.SetActive(IsCanUp());
            ui.upNeed.SetActive(IsCanUp());
            ShowSkillUpCostMoney();
            ShowTipState();
        }

        private bool IsCanUp()
        {
            return heroSkill.isUnlock && !heroSkill.isMaxLv;
        }

        private bool IsCanPreview()
        {
            return !(heroSkill.lv == 1 && heroSkill.isMaxLv);
        }

        private void ShowSkillBase()
        {
            ui.textType.text = APIUIHeroInfo.GetStrSkillType(heroSkill.cfgData.SkillType);
            ui.textCost.text = APIUIHeroInfo.GetStrUseSkillCost(heroSkill.cfgData.SPCost);
            ui.textCooldown.text = APIUIHeroInfo.GetStrUseSkillCooldown(heroSkill.cfgData.CoolDown);

            ui.textName.text = heroSkill.cfgData.Name;
            ui.textDes.text = heroSkill.cfgLv.EffectText;
        }

        private void ShowSkillUp()
        {
            bool isShowBtn = IsCanUp() && heroSkill.belongHero.level >= heroSkill.cfgLv.UpNeedHeroLv;
            ui.btnUp.SetActive(isShowBtn);

            int cnt = heroSkill.cfgLv.Cost.Count / APIUIConst.CostDefaultSpacing;
            costItems.RefillCells(cnt);

            ui.textDesPreview.text = heroSkill.cfgNextLv.EffectText;
        }

        private void ShowSkillUpCostMoney()
        {
            costMoney.Hide();
            if (heroSkill.cfgLv.GoldCost.Count > 0)
            {
                costMoney.Show(heroSkill.cfgLv.GoldCost[0], heroSkill.cfgLv.GoldCost[1]);
            }
        }

        private void ShowTipState()
        {
            string strState = "";
            if (!heroSkill.isUnlock)
            {
                strState = APIUIHeroInfo.GetStateStrUnlockSkill(heroSkill.cfgData.UnlockHeroLevel);
            }
            else if (!heroSkill.isMaxLv)
            {
                if (heroSkill.belongHero.level < heroSkill.cfgLv.UpNeedHeroLv)
                {
                    strState = APIUIHeroInfo.GetStateStrUpSkill(heroSkill.cfgLv.UpNeedHeroLv);
                }
            }
            else
            {
                strState = APIUIHeroInfo.GetStateStrMaxLv();
            }
            ui.textState.text = strState;
            ui.tipState.SetActive(strState != "");
        }

        #region 单击
        private void OnClickPreview()
        {
            var uData = UD_HeroSkillLvPreview.NewFromPool();
            uData.Sync(heroData, heroSkill.cid);
            OpenUI<UISkillLvPreview>(uData);
        }

        private void OnClickUp()
        {
            if (!costMoney.CheckIsEnough())
            {
                return;
            }

            SendUp().Forget();
        }
        private async UniTaskVoid SendUp()
        {
            var result = await HeroModule.NetCore.CS_upSkill(heroData.cid, heroSkill.cid);
            if (result.IsSuccess)
            {
                var cid = APIUIHeroInfo.NoticeCid_SuccesUpHeroSkill;
                NoticeModule.ShowNoticeNoCall(cid);

                heroSkill.UpLv();
                if (isActive)
                {
                    ShowSkillList();
                }
            }
        }
        #endregion

        private void OnCostItemChanged(UIN_CostItem item, int index)
        {
            int kStart = index * APIUIConst.CostDefaultSpacing;
            int cid = heroSkill.cfgLv.Cost[kStart];
            int numCost = heroSkill.cfgLv.Cost[kStart + 1];
            item.Show(cid, numCost);
        }

        private void ShowUpProgress()
        {
            upProgress.RefillCells(heroSkill.maxLv - 1);
        }

        private void OnUpProtressChanged(UIN_CommonDarkLight item, int index)
        {
            item.Show(index <= heroSkill.lv - 2);
        }
    }
}
